package controller

import (
	"fmt"
	"github.com/gin-contrib/sessions"
	redis2 "github.com/gin-contrib/sessions/redis" // 给包取别名 因为重复了
	"go.uber.org/zap"
	"go_web_learn/common"
	"go_web_learn/initconf"
	"runtime/debug"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

// 全局中间件-计算耗时
func GlobalMiddleware(c *gin.Context) {
	startTime := time.Now()
	// 调用请求的剩余程序 如果不执行的这个的话就会再这个方法执行完自动去执行下一个程序方法
	c.Next()
	// 终止请求的剩余程序函数 但是本方法下面的endTime都回执行
	//c.Abort()
	endTime := time.Now().UnixMilli()
	consumeTime := endTime - startTime.UnixMilli()
	// api写法
	since := time.Since(startTime)
	fmt.Println("消耗的时间为:", consumeTime, "since统计,", since)
}

// 全局中间件-异常拦截
func GlobalErrorHandle(c *gin.Context) {
	defer func() {
		err := recover()
		if err != nil {
			stack := string(debug.Stack()) // 获取panic时堆栈
			initconf.ErrorCtx(c, "全局异常了", zap.Any("error", err), zap.String("stack", stack))
			common.ResponseError(c, "系统异常")
		}
	}()
	c.Next()
}

// 添加链路traceNo
func GlobalTraceNoHandle(c *gin.Context) {
	uuid := uuid.New()
	c.Set("traceNo", uuid.String())
	c.Next()
}

// session中间件
func GlobalSession() gin.HandlerFunc {
	// 使用cookie模式 存在内存中给浏览器一个cookie
	//store := cookie.NewStore([]byte("secret111"))
	// 这个话也会给浏览器cookie 但是数据存储再redis种
	store, err := redis2.NewStore(10, "tcp", fmt.Sprintf("%s:%d", initconf.Conf.RedisConfig.Host, initconf.Conf.RedisConfig.Port), initconf.Conf.RedisConfig.Password, []byte("secret111"))
	if err != nil {
		panic(err)
	}
	return sessions.Sessions("mysession", store)
}
